package com.ning.reggie.common.myExpection;

import com.ning.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常处理类。
 * 用于统一处理应用程序中的异常情况。
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class}) // 注解表示这是一个全局的控制器增强类，会对带有 @RestController 和 @Controller 注解的控制器中的异常进行处理。
@ResponseBody // 注解表示这个类中的方法返回的结果会直接作为 HTTP 响应体返回，而不是通过视图解析器进行处理。
@Slf4j // Lombok 注解，为这个类添加日志对象 log，方便输出日志信息。
public class GlobalExceptionHandler {

    /**
     * 异常处理方法。
     * 专门用于处理 SQLIntegrityConstraintViolationException 类型的异常。
     *
     * @param ex 捕获到的 SQLIntegrityConstraintViolationException 异常对象。
     * @return 返回一个包含错误信息的通用响应对象 R，泛型参数为 String。
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class) // 注解表示这个方法用于处理指定类型的异常。当控制器方法抛出 SQLIntegrityConstraintViolationException 异常时，这个方法会被调用。
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        log.error(ex.getMessage()); // 记录异常信息到日志中。

        // 判断异常信息中是否包含"Duplicate entry"，如果包含，则表示有重复条目。
        if (ex.getMessage().contains("Duplicate entry")) {
            String[] split = ex.getMessage().split(" "); // 将异常信息按空格分割成字符串数组。
            String msg = split[2] + "已存在"; // 提取出重复的条目名称，并组成错误信息。
            return R.error(msg); // 返回包含错误信息的通用响应对象，表示该条目已存在。
        }

        return R.error("未知错误"); // 如果异常信息不包含"Duplicate entry"，则返回包含"未知错误"信息的通用响应对象。
    }


    /**
     * 异常处理方法。
     * 专门用于处理自定义的 CustomException 异常。
     *
     * @param ex 捕获到的 CustomException 异常对象。
     * @return 返回包含错误信息的通用响应对象 R，泛型参数为 String。
     */
    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex) {
        log.error(ex.getMessage());
        // 记录异常信息到日志中，并返回包含异常信息的通用响应对象。
        return R.error(ex.getMessage());
    }
}
